package com.darren.euc.service.impl;

import java.math.BigInteger;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import com.darren.euc.entity.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.darren.euc.dao.ClientDao;
import com.darren.euc.dao.ClientExtensionDao;
import com.darren.euc.dao.ClueDao;
import com.darren.euc.dao.MemberDao;
import com.darren.euc.dao.OrderDao;
import com.darren.euc.dao.UserDao;
import com.darren.euc.service.ClientService;
import com.darren.euc.util.Kv;
import com.darren.euc.util.StringUtil;

import net.sf.json.JSONObject;


@Service
public class ClientServiceImpl implements ClientService {

    private static final Logger log = Logger.getLogger(ClientServiceImpl.class);

    @Autowired
    private ClientDao clientDao;

    @Autowired
    private UserDao userDao;
    
    
    @Autowired
    private OrderDao orderDao;
    
    
    @Autowired
    private MemberDao memberDao;
    
    @Autowired
    private ClientExtensionDao clientExtensionDao;


    @Autowired
    private ClueDao clueDao;

    @Override
    public Client save(Client client) {
        for(ClientExtension extension:client.getClientExtensionList()){
            clientExtensionDao.save(extension);
        }
        client = clientDao.save(client);
        Clue clue = client.getClue();
        if(clue != null){
            clue.setClient(client);
            if(clue.getId() != null){
                clueDao.save(clue);
            }else{
                clueDao.update(clue);
            }
        }
        return client;
    }

    @Override
    public Client update(Client client) {
        //clientExtensionDao.deleteByClientId(client.getId());
        for(ClientExtension extension:client.getClientExtensionList()){
            clientExtensionDao.save(extension);
        }
        Clue clue = client.getClue();
        if(clue != null){
            clue.setClient(client);
            if(clue.getId() != null){
                clueDao.save(clue);
            }else{
                clueDao.update(clue);
            }
        }
        return clientDao.update(client);
    }


    @Override
    public void delete(Client client) {
        clientExtensionDao.deleteByClientId(client.getId());
        clientDao.delete(client);
    }

    @Override
    public List<Client> getAll() {
        return clientDao.getAll();
    }

    @Override
    public List<Client> getActiveclient() {
        return clientDao.getActiveclient();
    }
    
    public List<Client> getMemberClient(){
    	return clientDao.getMemberClient();
    }
    
    @Override
    public List<Client> getClientForMember() {
        return clientDao.getClientForMember();
    }

    @SuppressWarnings("rawtypes")
    public PageBean queryForPageUseHQL(JSONObject requestJson,Integer pageSize, Integer currentPage){
        String HQL = null;
        String likes = null;
        String equals = null;
        List<Object> parameters = new ArrayList<Object>();
        JSONObject likeJson = requestJson.getJSONObject("like");
        Iterator likeIterator = likeJson.keys();
        while(likeIterator.hasNext()){
            String key = (String) likeIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = likeJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
                likes = (likes == null?"": likes + " OR ") +  key + " like ? ";
                parameters.add("%"+value+"%");
            }
        }
        HQL = likes == null?null:(" (" + likes + ") ");
        JSONObject equalsJson = requestJson.getJSONObject("equals");
        Iterator equalsIterator = equalsJson.keys();
        while(equalsIterator.hasNext()){
            String key = (String) equalsIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = equalsJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
                if("visitTimeStart".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date startDate = (Date)format.parse(value);
                        parameters.add(startDate);
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    equals = (equals == null?"": ""+equals + " and ") +  " visitTime >= ? ";
                }else if("visitTimeEnd".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    try {
                        Date endDate = (Date)format.parse(value);
                        Calendar calendar = Calendar.getInstance();
                        calendar.setTime(endDate);
                        int day=calendar.get(Calendar.DATE);
                        calendar.set(Calendar.DATE,day+1);
                        parameters.add(calendar.getTime());
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    equals = (equals == null?"": ""+equals + " and ") +  " visitTime <= ? ";

                }else if("spaceId".equals(key)){
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(Integer.parseInt(value));
                }else if("enable".equals(key)){
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(Boolean.parseBoolean(value));
                }else{
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(value);
                }
            }
        }
        if(HQL != null){
            if(equals != null){
                HQL = HQL + " and " + equals;
            }
        }else{
            HQL = equals;
        }
        
        Integer userId = requestJson.getInt("userId");
        boolean isAdmin = userDao.IsAdmin(userId, 10000);
        if(isAdmin == true){
        	HQL = "select clue from Clue as clue where clue.processPerson is not null and clue.client is not null and enable = true and (select count(*) from clue.client.orderList orders) <= 0 " + (HQL == null?"  ":"   and " + HQL) + " order by createTime desc ";
        }else{
        	HQL = "select clue from Clue as clue where clue.processPerson is not null and clue.client is not null and enable = true and (select count(*) from clue.client.orderList orders) <= 0 " + (HQL == null?"  ":"   and " + HQL) + "  and clue.processPerson.id = ?  order by createTime desc ";
        	parameters.add(userId);
        }        
        return clueDao.queryForPageByHQL(HQL, pageSize, currentPage,parameters.toArray());
    }


    public PageBean queryCluesWithOrderOld(JSONObject requestJson,Integer pageSize, Integer currentPage){
        String HQL = null;
        String likes = null;
        String equals = null;
        List<Object> parameters = new ArrayList<Object>();
        JSONObject likeJson = requestJson.getJSONObject("like");
        Iterator likeIterator = likeJson.keys();
        while(likeIterator.hasNext()){
            String key = (String) likeIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = likeJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
                likes = (likes == null?"": likes + " OR ") +  key + " like ? ";
                parameters.add("%"+value+"%");
            }
        }
        HQL = likes == null?null:(" (" + likes + ") ");
        JSONObject equalsJson = requestJson.getJSONObject("equals");
        Iterator equalsIterator = equalsJson.keys();
        while(equalsIterator.hasNext()){
            String key = (String) equalsIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = equalsJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
                if("orderTimeStart".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        Date startDate = (Date)format.parse(value + " 00:00:00");
                        parameters.add(startDate);
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    equals = (equals == null?"": ""+equals + " and ") +  " (select count(*) from clue.client.orderList  orders where orders.salesTime >= ? ) > 0 ";
                    //equals = (equals == null?"": ""+equals + " and ") +  " salesTime >= ? ";
                }else if("orderTimeEnd".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        Date endDate = (Date)format.parse(value  + " 23:59:59" );
                        parameters.add(endDate);
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    equals = (equals == null?"": ""+equals + " and ") +  " (select count(*) from clue.client.orderList  orders where orders.salesTime <= ? ) > 0 ";
                    //equals = (equals == null?"": ""+equals + " and ") +  " salesTime <= ? ";
                }else if("spaceId".equals(key)){
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(Integer.parseInt(value));
                }else if("enable".equals(key)){
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(Boolean.parseBoolean(value));
                }else{
                    equals = (equals == null?"": ""+equals + " and ") +  key + " = ? ";
                    parameters.add(value);
                }
            }
        }
        if(HQL != null){
            if(equals != null){
                HQL = HQL + " and " + equals;
            }
        }else{
            HQL = equals;
        }
        HQL = " from Clue clue where enable = true and clue.client is not null and clue.client.orderList is not empty " + (HQL == null?"":" and " + HQL) ;
       // HQL = HQL + " order by createTime desc ";
        return clueDao.queryForPageByHQL(HQL, pageSize, currentPage,parameters.toArray());
    }
    
    
    
    
    @SuppressWarnings({ "rawtypes", "unchecked" })
    @Override
    public PageBean queryCluesWithOrder(JSONObject requestJson,Integer pageSize, Integer currentPage){
    	 String SQL = "SELECT orders.* "+
					"	from euc_orders as orders "+
					"	INNER JOIN euc_client as client on orders.client_id = client.id "+
					"	INNER JOIN euc_clues as clue on clue.client_id = client.id "+
					"	where clue.`enable` = '1' ";

        List<Object> parameters = new ArrayList<Object>();
		Integer userId = requestJson.getInt("userId");
		boolean isAdmin = userDao.IsAdmin(userId, 10000);
		if (isAdmin == false) {	
			SQL += " and clue.process_person = ? ";
			parameters.add(userId);
		}
        JSONObject likeJson = requestJson.getJSONObject("like");
        Iterator likeIterator = likeJson.keys();
        while(likeIterator.hasNext()){
            String key = (String) likeIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = likeJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
            	if("client.companyName".equals(key)){
            		SQL += " and case client.client_type WHEN '个人' then client.member_name  when '企业' then client.company_name end like ?  ";
            		parameters.add("%"+value+"%");
            	}
            }
        }

        JSONObject equalsJson = requestJson.getJSONObject("equals");
        Iterator equalsIterator = equalsJson.keys();
        while(equalsIterator.hasNext()){
            String key = (String) equalsIterator.next();
            key = StringUtil.convertNullToEmptyString(key);
            String value = equalsJson.getString(key);
            value = StringUtil.convertNullToEmptyString(value);
            if(!"".equals(value)){
                if("orderTimeStart".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        Date startDate = (Date)format.parse(value + " 00:00:00");
                        parameters.add(startDate);
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    SQL += " and orders.create_time >= ? ";
                }else if("orderTimeEnd".equals(key)){
                    DateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    try {
                        Date endDate = (Date)format.parse(value  + " 23:59:59" );
                        parameters.add(endDate);
                    } catch (ParseException e) {
                        log.error(e.getMessage(),e);
                    }
                    SQL += " and orders.create_time <= ? ";
                }else if("cityId".equals(key)){
                    SQL += " and clue.city_id = ? " ;
                    parameters.add(value);
                }else if("spaceId".equals(key)){
                    SQL += " and clue.space_id = ? " ;
                    parameters.add(Integer.parseInt(value));
                }else if("orderId".equals(key)){
                	SQL += " and orders.id = ? " ;
                    parameters.add(Integer.parseInt(value));
                }
            }
        } 
        SQL += " order by orders.create_time desc ";
        PageBean pageBean = orderDao.queryForPageBySQL(SQL, pageSize, currentPage,parameters.toArray());
        List<Clue> clues = new ArrayList<Clue>();
        if(pageBean.getList() != null && pageBean.getList().size() > 0){
        	List<Order> orders = (List<Order>)pageBean.getList();
        	for(int i = 0; i < orders.size(); i++){
        		Order order = orders.get(i);
        		order.setOrderByNumber(i+1);
        		Clue clue = clueDao.findByClientId(order.getClientId());
                //clue = filterClueFlowByOrderId(clue,order.getId());
        		clues.add(clue);
        	}
        }
        pageBean.setList(clues);        
        return pageBean;
    }

    private Clue filterClueFlowByOrderId(Clue clue, Integer orderId) {
        if(clue.getClueFollowList()!=null && clue.getClueFollowList().size()>0){
            List<ClueFollow> newClueFollow = new ArrayList<>();
            /*for(ClueFollow clueFollow:clue.getClueFollowList()){
               // if(judgeMatch(clueFollow,orderId)){
                  //  newClueFollow.add(clueFollow);
               // }
            }      */     
          // clue.setClueFollowList(newClueFollow);
        }
        return  clue;
    }

    private boolean judgeMatch(ClueFollow clueFollow, Integer orderId) {
        if(clueFollow.getOrderId() != null && clueFollow.getOrderId().equals(orderId)){
            return true;
        }
        return false;
    }

    @SuppressWarnings("unchecked")
	@Override
    public PageBean queryCluesWithClient(JSONObject requestJson,Integer pageSize, Integer currentPage){
        List<Object> parameters = new ArrayList<Object>();
        //"clientName":parameter,'clientType':clientType,'clientStatus':clientStatus
        String clientName = requestJson.getString("clientName");
        String clientType = requestJson.getString("clientType");
        String clientStatus = requestJson.getString("clientStatus");
        String SQL = "select distinct clue.* "
                +" from euc_clues clue "
                +" INNER JOIN euc_client client on clue.client_id = client.id "
                +" INNER JOIN euc_orders orders  on client.id = orders.client_id "
                +" INNER JOIN euc_contracts contract on contract.order_id = orders.id "
                +" where 1 = 1 ";
        if(clientType != null && !"".equals(clientType)){
            SQL += " and client.client_type = ? ";
            parameters.add(clientType);
        }
        if(clientName != null && !"".equals(clientName.trim())){
            SQL += " and (client.member_name like ? or company_name like ? ) ";
            parameters.add("%"+clientName+"%");
            parameters.add("%"+clientName+"%");
        }
        if("已入驻".equals(clientStatus)){
            SQL +=   " and EXISTS(select 1 from euc_contract_product product "
                    +" 				where product.contract_id = contract.id "
                    +"				and datediff(product.rent_start,CURDATE()) <=0 "
                    +"				and datediff(product.rent_end,CURDATE()) >=0 )  ";///*已入驻,未离场*/
        }else if("已签约".equals(clientStatus)){
            SQL +=   " and orders.id is not NULL  "
                    +" and ((EXISTS(select 1 from euc_contract_product product  "
                    +" 										where product.contract_id = contract.id "
                    +" 											and datediff(CURDATE(),product.rent_start) < 0) "
                    +" 			AND EXISTS(select 1 from euc_contract_product product  "
                    +" 										where product.contract_id = contract.id) "
                    +" 			AND NOT EXISTS(select 1 from euc_contract_product product  "
                    +" 										where product.contract_id = contract.id "
                    +" 											and datediff(product.rent_start,CURDATE()) < 0)) "
                    +" 		OR NOT EXISTS(select 1 from euc_contract_product product  "
                    +" 										where product.contract_id = contract.id)) ";


        }else if("已离场".equals(clientStatus)){
            SQL +=   " and not EXISTS(select 1 from euc_contract_product product "
                    +" 							where product.contract_id = contract.id "
                    +" 								and datediff(product.rent_end,CURDATE()) >= 0 ) "
                    +" 	and EXISTS(select 1 from euc_contract_product product  "
                    +" 						where product.contract_id = contract.id ) ";/*已离场*/
        }
        SQL += " ORDER BY client.id desc ";
        PageBean pageBean = clueDao.queryForPageBySQL(SQL, pageSize, currentPage,parameters.toArray());        
        List<Clue> clues = pageBean.getList();
        for(Clue clue:clues){
        	Client client = clue.getClient();
        	if(client != null){
        		BigInteger memberCount = memberDao.findByClientID(client.getId());
        		client.setMemberCount(memberCount);
        	}
        }
        return pageBean;
        //return clueDao.queryForPageBySQL(SQL, pageSize, currentPage,parameters.toArray());
    }

    @Override
    public PageBean queryCluesWithEnterClient(JSONObject requestJson,Integer pageSize, Integer currentPage){
        List<Object> parameters = new ArrayList<Object>();
        //"clientName":parameter,'clientType':clientType,'clientStatus':clientStatus
        String roomName = requestJson.getString("roomName");
        String clientType = requestJson.getString("clientType");
        String spaceId = requestJson.getString("spaceId");
        String SQL = "select distinct clue.* "
                +" from euc_clues clue "
                +" INNER JOIN euc_client client on clue.client_id = client.id "
                +" LEFT JOIN euc_orders orders  on client.id = orders.client_id "
                +" LEFT JOIN euc_contracts contract on contract.order_id = orders.id "
                +" where 1 = 1 ";
        if(clientType != null && !"".equals(clientType)){
            SQL += " and client.client_type = ? ";
            parameters.add(clientType);
        }
        if(spaceId != null && !"".equals(spaceId)){
            SQL += " and orders.space_id = ? and orders.space_id is not null  ";
            parameters.add(Integer.parseInt(spaceId));
        }
        if(roomName != null && !"".equals(roomName.trim())){
        	SQL +=   " and EXISTS(select 1 from euc_contract_product product "
                    +" 				where product.contract_id = contract.id "
                    +"				and product.room_name like ? )  ";///*房间名*/
            parameters.add("%"+roomName+"%");
        }
        SQL +=   " and EXISTS(select 1 from euc_contract_product product "
                +" 				where product.contract_id = contract.id "
                +"				and datediff(product.rent_start,CURDATE()) <=0 "
                +"				and datediff(product.rent_end,CURDATE()) >=0 )  ";///*已入驻,未离场*/
        SQL +=  "order  by (SELECT	min(product.rent_start)	FROM	euc_contract_product product	WHERE	product.contract_id = contract.id	AND datediff(product.rent_start,CURDATE()) <= 0	AND datediff(product.rent_end, CURDATE()) >= 0)  desc ";
        return clueDao.queryForPageBySQL(SQL, pageSize, currentPage,parameters.toArray());
    }
    
    @Override
    public List<Clue> queryCluesByClientName(String clientName){
        String 	HQL = " from Clue clue where enable = true and clue.client is not null and clue.client.orderList is not empty and (clue.client.companyName like ? or clue.client.memberName like ? )" ;
        List<Object> parameters = new ArrayList<Object>();
        parameters.add("%"+clientName+"%");
        parameters.add("%"+clientName+"%");
        return clueDao.queryByCondition(HQL, parameters.toArray());
    }

    @Override
    public List<Clue> queryCluesByClientNameEqual(String clientName) {
        String 	HQL = " from Clue clue where enable = true and clue.client is not null and clue.client.orderList is not empty and (clue.client.companyName = ?  )" ;
        List<Object> parameters = new ArrayList<Object>();
        parameters.add(clientName);
         return clueDao.queryByCondition(HQL, parameters.toArray());
    }

    @Override
    public PageBean findPage(Map para, Integer pn, Integer ps) {
        pn = 1;
        ps = 10;
        String select = "select a.* ";
        String from = " from euc_client a left join euc_orders b on a.id = b.client_id where 1=1 and b.client_id is not null ";
        if (para.get("type") != null)
            from += " and a.client_type="+para.get("type");//TODO:确定企业“服务类型”字段是哪一个

        from += " order by b.sales_time desc ";

        PageBean<Client> pageBean = clientDao.queryForPageBySQL(select + from, ps, pn);

        //TODO:字段模糊不清
        List list = new ArrayList();
        pageBean.getList().forEach(x->{
            Map map = new HashMap();
            map.put("client_id", x.getId());
            map.put("clientName", x.getCompanyName());
            map.put("pic",x.getLogoUrl());
            map.put("typeName", x.getClientType());

            list.add(map);
        });
        pageBean.setList(list);
        return pageBean;
    }

    @Override
    public Map clientDetail(Integer client_id) {
        Client client = clientDao.findById(client_id);

        if (client != null){
            return Kv.of("client_id", client.getId())
                    .set("clientName", client.getCompanyName())
                    .set("pic", client.getLogoUrl())
                    .set("typeName", client.getClientType())
                    .set("businessScope", client.getCompanyBusinessScope())
                    .set("clientUrl", "")
                    .set("phone", "")
                    .set("desc", client.getRemark())
                    .set("personCount", "");
        }
        //todo:pic clientUrl  phone  personCount

        return null;
    }

    @Override
    public Clue findByClientId(int clientId) {
        Clue clue = clueDao.findByClientId(clientId);
        return clue;
    }

    @Override
    public String judgeFull(Integer alreadyIn,Integer clientId) {
        //获取所有工位
        Integer allSeats = this.getAllRentSeats(clientId);
        log.info("judge Full:"+alreadyIn+",seats:"+allSeats);
        if(allSeats == 0){
            return "合同没有工位";
        }
        if(alreadyIn < allSeats+2)
            return null;
        return "已经达到最大可加会员数目";
    }

    private Integer getAllRentSeats(Integer clientId) {
        if(clientId <1){
         log.info("[client] clientId is null");
            return 0;
        }
    	BigInteger seatCount = clientDao.getAllRentSeats(clientId);
    	if(seatCount == null){
    		return 0; 
    	}
        return Integer.valueOf(seatCount.toString());
    }

}